#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include "estruturas.h"
#include "par.h"
//#include "oneStep.h"
//#include "gravaalsa.h"
#include "gravaoss.h"
#include "herrmanNey.h"

void reconheceFrases
(
    struct configBusca searchConfig, // search algorithm configurations	
	struct modelo_HMM HMM, // acoustic models
	struct bigram *grammar, // stores the bigram information
	long nTerms,	// number of entries in the grammar
	struct vocab vocabulary, // stores the vocabulary
	int MaxProfundidade, // profundidade maxima observada em todas as arvores lexicas
	int n_arvores, // numero de arvores geradas a partir do arquivo de vocabulario
    int* n_nos, // numero de nos em cada arvore
    struct no ***vocab, // armazena as palavras do vocabulario em arvores
    int ***lista, // estrutura que armazena os nos pertencentes a cada nivel, para cada arvore
    int *profundidades, // indica a profundidade do no mais profundo em cada arvore
    int **quantos // indica quantos elementos existem em cada nivel de cada uma das listas
)
{	
	struct locucao x; // stores the acoustic parameters of the utterance to be recognized
	int j; // counters	
	char frase[512]; // recognized string
	time_t t_inic,t_final; // instantes inicial e final
	int decorrido;
	short *buffer; // contains the utterance to be recognized
	int nSamples; // number of samples in audio buffer
	short bps=16; // bits por amostra
    int fs=11025; // frequencia de amostragem do sinal
    int maxTime=2; // maximun audio record time in seconds
    	
	// Gravando locução a ser reconhecida
	buffer=(short *)malloc(maxTime*fs*sizeof(short)); // 2 seconds at fs=11025 and 16 bits quantization
	nSamples = gravaoss(buffer,bps,fs,maxTime);
   
    FILE *fp;
	if ((fp = fopen("loc.raw", "wb"))==NULL)
    {
      printf("Cannot open file \n");
      exit(1);
    }

    if (fwrite(buffer, sizeof(short), nSamples, fp) !=nSamples)
    {
     printf("Write error occurred");
     exit(1);
    }
    
    fclose(fp);
   
//////////////////////////////////////////////////////////////////////////////////////////
// For valgrind profiling
/*   
    tamanho=44100;
    FILE *fp;
	if ((fp = fopen("loc.raw", "r"))==NULL)
    {
      printf("Cannot open file \n");
      exit(1);
    }
    if (fread(buffer, tamanho, 1, fp) != 1)
    {
     printf("Read error occurred");
     exit(1);
    }
    fclose(fp);

	if ((fp = fopen("loc1.raw", "wb"))==NULL)
    {
      printf("Cannot open file \n");
      exit(1);
    }
    if (fwrite(buffer, tamanho, 1, fp) !=1)
    {
     printf("Write error occurred");
     exit(1);
    }
    fclose(fp);
*/
// end of valgrind profiling    
////////////////////////////////////////////////////////////////////////////////////
   	// Iniciando contagem de tempo de processamento
    time(&t_inic);
    
    // Parametrizando sinal de voz (aloca ponteiro 'x')
    // CalcPar e definido em Par.h
    // bUsaPCA,NomePCA,OrdemRed definidos em HMM.h
	calcpar(buffer,nSamples,bps,fs,HMM.ordem,HMM.delta,&x.n_quadros,&x.par);

	// Reconhecendo frase
    HerrmanNey(x,frase,searchConfig,HMM,grammar,nTerms,vocabulary,MaxProfundidade,n_arvores,n_nos,vocab,lista,profundidades,quantos);

    // removing control characters (\r \n) frm the end of string
	while (frase[strlen(frase)-1]=='\r' || frase[strlen(frase)-1]=='\n')
		frase[strlen(frase)-1] = '\0';
		
    // Parando cronometragem
    time(&t_final);

    // Calculando tempo decorrido
    decorrido = (int) difftime(t_final,t_inic);
	printf("Tempo: %d segundos\n",decorrido);
    
    // Apresentando frase reconhecida
    printf("%s\n",frase);

    // Desalocando ponteiros
    for (j=0;j<x.n_quadros;j++)
        free(x.par[j]);
    free(x.par);
    free(buffer);	
}
